﻿using System;
using System.Collections.Generic;
using Evpo.ContactData.Common;
using System.Data.SqlClient;
using System.Data;

namespace Evpo.ContactData.Data
{
    public class AddressAdapter : AdapterBase
    {
        public AddressAdapter(Connection connection) : base(connection) { }

        #region Fields
        #endregion

        #region Properties
        protected override string PrimaryKeyField
        {
            get { return Fields.ContactAddressID; }
        }

        protected override string SProcToDelete
        {
            get { return SProcs.DeleteAddress; }
        }

        protected override string SProcToLoad
        {
            get { return SProcs.GetAddress; }
        }

        protected override string SProcToSave
        {
            get { return SProcs.SaveAddress; }
        }

        protected override string SProcToQuery
        {
            get { return SProcs.GetAddresses; }
        }
        #endregion

        #region Methods

        public List<Address> QueryAddresses(AddressQueryParameters queryParameters, out int addressCount)
        {
            addressCount = -1;

            var addressCountParam =
                new SqlParameter("@Count", SqlDbType.Int)
                {
                    Direction = ParameterDirection.Output
                };

            var parameters = new List<SqlParameter>()
            {
                addressCountParam,
            };

            if (queryParameters.PageBegin.HasValue)
                parameters.Add(new SqlParameter("@PageBegin", queryParameters.PageBegin.Value));

            if (queryParameters.PageEnd.HasValue)
                parameters.Add(new SqlParameter("@PageEnd", queryParameters.PageEnd.Value));

            if (!String.IsNullOrEmpty(queryParameters.LinesContain))
                parameters.Add(new SqlParameter("@LinesContain", queryParameters.LinesContain));

            if (!String.IsNullOrEmpty(queryParameters.SuburbContains))
                parameters.Add(new SqlParameter("@SuburbContains", queryParameters.SuburbContains));

            if (!String.IsNullOrEmpty(queryParameters.State))
                parameters.Add(new SqlParameter("@State", queryParameters.State));

            if (!String.IsNullOrEmpty(queryParameters.Postcode))
                parameters.Add(new SqlParameter("@Postcode", queryParameters.Postcode));

            if (!String.IsNullOrEmpty(queryParameters.Country))
                parameters.Add(new SqlParameter("@CountryContains", queryParameters.Country));

            var retList = new List<Address>();

            FillFromQuery<Address>(parameters, retList);

            addressCount = (int)addressCountParam.Value;
            return retList;

        }

        public Address Load(int addressID)
        {
            return Load<Address>(addressID);
        }

        public void Save(Address address, bool isNew)
        {
            Save<Address>(address, isNew);
        }

        internal static void FillAddressParametersToSave(Address address, List<SqlParameter> paramList)
        {
            if (paramList == null)
                throw new ArgumentNullException("paramList");

            paramList.Add(new SqlParameter("@" + Fields.Line1, address.Line1));
            paramList.Add(new SqlParameter("@" + Fields.Line2, address.Line2));
            paramList.Add(new SqlParameter("@" + Fields.Suburb, address.Suburb));
            paramList.Add(new SqlParameter("@" + Fields.Postcode, address.Postcode));
            paramList.Add(new SqlParameter("@" + Fields.State, address.State));
            paramList.Add(new SqlParameter("@" + Fields.Country, address.Country));
        }

        internal static void FillFieldsFromReader(Address address, ProcedureOutputReader procReader)
        {
            address.ContactAddressID = procReader.GetID(Fields.ContactAddressID);
            address.Line1 = procReader.GetString(Fields.Line1);
            address.Line2 = procReader.GetString(Fields.Line2);
            address.Suburb = procReader.GetString(Fields.Suburb);
            address.State = procReader.GetString(Fields.State);
            address.Postcode = procReader.GetString(Fields.Postcode);
            address.Country = procReader.GetString(Fields.Country);
        }

        #endregion Methods

        #region Classes
        private class Fields
        {
            internal const string ContactAddressID = "ContactAddressID";
            internal const string Line1 = "Line1";
            internal const string Line2 = "Line2";
            internal const string Suburb = "Suburb";
            internal const string State = "State";
            internal const string Postcode = "Postcode";
            internal const string Country = "Country";
        }
        #endregion Classes
    }
}
